//
//  MainGameScene.m
//  ProjectL
//
//  Created by Nguyen Tan Loc on 8/17/13.
//  Copyright (c) 2013 Nguyen Tan Loc. All rights reserved.
//

#import "MainGameScene.h"
#import "PhysicSystem.h"
#import "PhysicInterface.h"
#import "LosePopup.h"
#import "WinPopup.h"
#import "RequirePopup.h"
#import "Utility.h"
#import "CalibrateAccelerometer.h"
#import "Setting.h"
#import "CalibratePopup.h"
#import "LevelChoosingScene.h"
#import "DefineXML.h"
#import "ShieldZone.h"
#import "SharePopup.h"
#import "SimpleAudioEngine.h"

@implementation MainGameScene
@synthesize _mainGameUI = mMainGameUI;
@synthesize _darkFog = mDarkFog;
@synthesize _mainGameState = mState;
@synthesize _globalBatch = mGlobalBatch;
@synthesize _isShopJustClose = mIsShopJustClose;

static MainGameScene *m_Instance = nil;

+(MainGameScene *) getInstance
{
    return m_Instance;
}

+(CCScene *) scene
{
    CCScene *scene = [CCScene node];
    
    MainGameUI *ui = [MainGameUI node];
    MainGameScene *layer = [[MainGameScene alloc] initWithMainUI:ui];

    m_Instance = layer;

    [scene addChild:layer z:Z_MAIN_GAME];
    [scene addChild:ui z:Z_MAIN_UI];
    [layer release];
    return scene;
}

-(id) initWithMainUI:(MainGameUI *)mainGameUI
{
    if (self = [super init])
    {
        mMainGameUI = mainGameUI;
        mIsShopJustClose = NO;
        
        [self loadGame];
        [self startGame];
        
        if (![Setting getInstance]._isCalibrate)
        {
            [mMainGameUI addChild:[[[CalibratePopup alloc] initWithoutStartFade] autorelease] z:Z_CALIBRATE_POPUP];
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(activeTouchAndAccel) name:EVENT_CALIBRATE_POPUP_CLOSE object:nil];
        }
        else
        {
            [self activeTouchAndAccel];
        }
        
        // add event when bomb explode
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(shakeScreen) name:EVENT_BOMB_EXPLOSION object:nil];
    }
    
    return self;
}

-(void) activeTouchAndAccel
{
    self.touchEnabled = YES;
    self.accelerometerEnabled = YES;
}

-(void) registerWithTouchDispatcher
{
    [[[CCDirector sharedDirector] touchDispatcher] addTargetedDelegate:self priority:TOUCH_PRIORITY_MAIN_GAME swallowsTouches:YES];
}

-(BOOL) ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event
{
//    CGPoint touchLocation = [[CCDirector sharedDirector] convertTouchToGL:touch];

//    for (CCNode *child in [self children]) {
//        [child pauseSchedulerAndActions];
//        
//    }
    
//    if (mState != sMG_ENDING)
//    {
//        Path *path = [mListPath objectAtIndex:0];
//        [path processTouch:touch.phase position:ccp(touchLocation.x, touchLocation.y + 50)];
//    }
    
//    if ([LevelManager getInstance]._isDarkFog && mState == sMG_STARTING)
//        [mDarkFog setSpotLightPosition:touchLocation];
    
    return YES;
}

-(void) ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event
{
//    CGPoint touchLocation  = [[CCDirector sharedDirector] convertTouchToGL:touch];
    
//    if (mState != sMG_ENDING)
//    {
//        Path *path = [mListPath objectAtIndex:0];
//        [path processTouch:touch.phase position:ccp(touchLocation.x, touchLocation.y + 50)];
//    }
    
//    if ([LevelManager getInstance]._isDarkFog && mState == sMG_STARTING)
//        [mDarkFog setSpotLightPosition:touchLocation];
}

-(void) ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event
{
    CGPoint touchLocation = [[CCDirector sharedDirector] convertTouchToGL:touch];
    
    Path *path = [mListPath objectAtIndex:0];
//    if (mState != sMG_ENDING)
//    {
//        [path processTouch:touch.phase position:ccp(touchLocation.x, touchLocation.y + 20)];
//    }
    
    if (mState == sMG_PREPARING && mMainGameUI._menuType == eMT_HIDE)
    {
        if (CGRectContainsPoint([path getDotCirleRect], touchLocation))
        {
            [self jailBreak];
        }
    }

//    if (mState == sMG_STARTING) // lose if game is started
//    {
//        [self endGame:eGT_RELEASE_TOUCH];
//    }
}

-(void) accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration
{    
    Path *path = [mListPath objectAtIndex:0];
    if (mState == sMG_ENDING)
    {
        return;
    }
    
    [[CalibrateAccelerometer getInstance] calibrate:acceleration];
    [path setGravity:ccp([CalibrateAccelerometer getInstance]._x * SPEED_NODE, [CalibrateAccelerometer getInstance]._y * SPEED_NODE)];
    
//    CCLOG(@"speedY = %f", [CalibrateAccelerometer getInstance]._y * SPEED_NODE);
}

-(void) jailBreak
{
    Path *path = [mListPath objectAtIndex:0];
    [path jailBreak];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResume) name:EVENT_ON_COUNT_DONE object:nil];
    mState = sMG_JAILBREAKING;
}

-(void) pause
{
    CCLOG(@"main game pause");
    self.accelerometerEnabled = NO;
    [self pauseSchedulerAndActions];
}

-(void) resume
{
    CCLOG(@"resume");
    if (mState == sMG_PREPARING || mState == sMG_JAILBREAKING)
    {
        self.accelerometerEnabled = YES;
        [self resumeSchedulerAndActions];
    }
    else if (mState == sMG_STARTING)
    {
        Path *path = [mListPath objectAtIndex:0];
        [path showCountOnUserNode];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onResume) name:EVENT_ON_COUNT_DONE object:nil];
    }
}

-(void) onResume
{
    if (mState == sMG_JAILBREAKING && ![LevelManager getInstance]._isStartNow)
    {
        [self startAction];
    }
    
    
    CCLOG(@"onResume");
    mState = sMG_STARTING;
    self.accelerometerEnabled = YES;
    [self resumeSchedulerAndActions];
    
    [[NSNotificationCenter defaultCenter] removeObserver:self name:EVENT_ON_COUNT_DONE object:nil];
}

-(void) onEnter
{
    [super onEnter];
    CCLOG(@"on enter");
    
    if (mIsShopJustClose)
    {
        [self pause];
        [self resume];
        mIsShopJustClose = NO;
    }
}

-(void) pauseSchedulerAndActions
{
    [super pauseSchedulerAndActions];
    for (CCNode *child in mGlobalBatch.children)
    {
        [child pauseSchedulerAndActions];
    }
    
    Path *path = [mListPath objectAtIndex:0];
    [path pauseSchedulerAndActions];
}

-(void) resumeSchedulerAndActions
{
    [super resumeSchedulerAndActions];
    for (CCNode *child in mGlobalBatch.children)
    {
        [child resumeSchedulerAndActions];
    }
    
    Path *path = [mListPath objectAtIndex:0];
    [path resumeSchedulerAndActions];
}

-(void) shakeScreen
{
    mShakyTime = 0.15;
    [self unschedule:@selector(updateShakeScreen:)];
    [self schedule:@selector(updateShakeScreen:)];
}

-(void) updateShakeScreen:(ccTime)delta
{
    mShakyTime -= delta;
    if (mShakyTime <= 0)
    {
        [self unschedule:_cmd];
        [self setPosition:CGPointZero];
    }
    else
    {
        [self setPosition:ccp(rand() % 20, rand() % 20)];
    }
}

-(void) update:(ccTime)delta
{
    PhysicSystem::getInstance()->mWorld->Step(delta, 1, 1);
    
    if (mState == sMG_STARTING && [LevelManager getInstance]._levelTime > 0)
    {
        [LevelManager getInstance]._levelTime -= delta;
        if ([LevelManager getInstance]._levelTime <= 0)
        {
            // lose here
            [LevelManager getInstance]._levelTime = 0;
            [self endGame:eGT_OUT_OF_TIME];
        }
    }
    
    if (mState != sMG_PREPARING)
        [mMainGameUI updateTime];
    
    Path *path = [mListPath objectAtIndex:0];
    [path updateUserNode:delta];
}

-(void) draw
{
//    PhysicSystem::getInstance()->drawDebug();
}

-(void) loadLevel
{
    CCLOG(@"load level");
    mGlobalBatch = [CCSpriteBatchNode batchNodeWithFile:IMAGE_INGAME];
    [self addChild:mGlobalBatch z:Z_ORDER_BATCH];
    
    // load path
    mListPath = [[[LevelManager getInstance] getListPath] retain];
    for (int i = 0; i < mListPath.count; i++)
    {
        Path *path = [mListPath objectAtIndex:i];
        [path addToBatch:mGlobalBatch];
        [self addChild:path z:Z_ORDER_PATH];
    }
    
    // load bomb
    mListBomb = [[[LevelManager getInstance] getListBomb] retain];
    for (int i = 0; i < mListBomb.count; i++)
    {
        Bomb *bomb = [mListBomb objectAtIndex:i];
        [mGlobalBatch addChild:bomb z:Z_ORDER_BOMB];
        
        BombIndicator *bombIndicator = [[BombIndicator alloc] initWithBomb:bomb];
        [mGlobalBatch addChild:bombIndicator z:Z_ORDER_BOMB_INDICATOR];
        [bombIndicator release];
    }
    
    // load lazer
    mListLazer = [[[LevelManager getInstance] getListLazer] retain];
    for (int i = 0; i < mListLazer.count; i++)
    {
        Lazer *lazer = [mListLazer objectAtIndex:i];
        [lazer addToBatch:mGlobalBatch];
        [self addChild:lazer z:Z_ORDER_LAZER];
    }
    
    // load bouncing ball
    mListBouncBall = [[[LevelManager getInstance] getListBouncBall] retain];
    for (int i = 0; i < mListBouncBall.count; i++)
    {
        BouncingBall *bouncBall = [mListBouncBall objectAtIndex:i];
        [mGlobalBatch addChild:bouncBall z:Z_ORDER_BOUNC_BALL];
        [mGlobalBatch addChild:[bouncBall getGlow] z:Z_ORDER_BOUNC_BALL_G];
        [mGlobalBatch addChild:[bouncBall getEye] z:Z_ORDER_BOUNC_BALL_E];
        
        Path *path = [mListPath objectAtIndex:0];
        bouncBall._userNode = [path getUserNode];
    }
    
    // load energy
    mListEnergy = [[[LevelManager getInstance] getListEnergy] retain];
    for (int i = 0; i < mListEnergy.count; i++)
    {
        Energy *energy = [mListEnergy objectAtIndex:i];
        [mGlobalBatch addChild:energy z:Z_ORDER_ENERGY];
    }
    
    // load item
    
    // load decor
    
    // dark fog
    if ([LevelManager getInstance]._isDarkFog)
    {
        Path *p = [mListPath objectAtIndex:0];
        mDarkFog = [[DarkFog alloc] init];
        [mDarkFog setSpotLightPosition:[p getUserNode].position];
        [mDarkFog setSpotLightScale:DARK_FOG_ZOOM_OUT];
        if (![LevelManager getInstance]._isNewLevel)
        {
            [mDarkFog zoomIn];
        }
        else
        {
            [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onRequirePopupClose) name:EVENT_REQUIRE_POPUP_CLOSE object:nil];
        }
        [self addChild:mDarkFog z:Z_ORDER_DARK_FOG];
    }
    
    mListTutorial = [[[LevelManager getInstance] getListTutorial] retain];
    for (int i = 0; i < mListTutorial.count; i++)
    {
        CCNode *node = [mListTutorial objectAtIndex:i];
        [self addChild:node z:Z_ORDER_TUTORIAL];
    }
    
//    [[[CCDirector sharedDirector] scheduler] setTimeScale:0.2];
}

-(void) onRequirePopupClose
{
    if (mDarkFog != nil)
       [mDarkFog zoomIn];
}

-(void) destroyObjects
{
    [mGlobalBatch removeAllChildren];
    [self removeAllChildren];
    
    
    [mListPath release];
    mListPath = nil;
    
    [mListBomb release];
    mListBomb = nil;
    
    [mListBouncBall release];
    mListBouncBall = nil;
    
    [mListEnergy release];
    mListEnergy = nil;
    
    [mListLazer release];
    mListLazer = nil;
    
    if (mDarkFog != nil)
    {
        [mDarkFog release];
        mDarkFog = nil;
    }
}

-(void) startAction
{
    for (int i = 0; i < mListPath.count; i++)
    {
        Path *path = [mListPath objectAtIndex:i];
        [path startAction];
    }
    
    
    for (int i = 0; i < mListBomb.count; i++)
    {
        Bomb *bomb = [mListBomb objectAtIndex:i];
        [bomb startAction];
    }
    
    for (int i = 0; i < mListLazer.count; i++)
    {
        Lazer *lazer = [mListLazer objectAtIndex:i];
        [lazer startAction];
    }
    
    for (int i = 0; i < mListEnergy.count; i++)
    {
        Energy *energy = [mListEnergy objectAtIndex:i];
        [energy startAction];
    }
    
    for (int i = 0; i < mListBouncBall.count; i++)
    {
        BouncingBall *bouncBall = [mListBouncBall objectAtIndex:i];
        [bouncBall startAction];
    }
}

-(void) stopAction
{
    for (int i = 0; i < mListPath.count; i++)
    {
        Path *path = [mListPath objectAtIndex:i];
        [path stopAction];
    }
    
    for (int i = 0; i < mListBomb.count; i++)
    {
        Bomb *bomb = [mListBomb objectAtIndex:i];
        [bomb stopAction];
    }
    
    for (int i = 0; i < mListLazer.count; i++)
    {
        Lazer *lazer = [mListLazer objectAtIndex:i];
        [lazer stopAction];
    }
    
    for (int i = 0; i < mListEnergy.count; i++)
    {
        Energy *energy = [mListEnergy objectAtIndex:i];
        [energy stopAction];
    }
    
    for (int i = 0; i < mListBouncBall.count; i++)
    {
        BouncingBall *bouncBall = [mListBouncBall objectAtIndex:i];
        [bouncBall stopAction];
    }
}

-(void) loadGame
{
    CCLOG(@"load game");
    mState = sMG_PREPARING;
    
    [[LevelManager getInstance] loadCurrentLevel];
    [self loadLevel];
    
    
    [mMainGameUI updateEnergy];
    [mMainGameUI updateTime];
    [mMainGameUI checkAvailableUI];
    [mMainGameUI checkAvailableItem];
    [mMainGameUI updateLabelLevel];
    //    [mMainGameUI showItem:YES];
}

-(void) startGame
{
    CCLOG(@"start game");
    
    if ([LevelManager getInstance]._isNewLevel)
    {
        // show share popup
        [[SharePopup getInstance] showSharePopup];
        
        [LevelManager getInstance]._isNewLevel = NO;
        RequirePopup *popup = [[RequirePopup alloc] init];
        [mMainGameUI addChild:popup z:Z_RESULT_POPUP];
        [popup release];
    }
    
    [self scheduleUpdate];
    if ([LevelManager getInstance]._isStartNow)
    {
        [self startAction];
    }
}

-(void) endGame
{
    CCLOG(@"end game");
    [self unscheduleUpdate];
    [self stopAction];
    PhysicSystem::getInstance()->destroyAllBody();
    [self destroyObjects];
    
}

-(void) replay
{
    [self endGame];
    [self loadGame];
    [self startGame];
}

-(void) nextLevel
{
//    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if (![[LevelManager getInstance] isAvailableNextLevel])
    {
        [[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:0.5 scene:[LevelChoosingScene sceneEx]]];
        return;
    }
    
    [LevelManager getInstance]._currentLevel++;
    [LevelManager getInstance]._isNewLevel = YES;
    [self endGame];
    [self loadGame];
    [self startGame];
}

-(void) endGame:(ENDGAME_TYPE)type
{
    mState = sMG_ENDING;
    Path *path = [mListPath objectAtIndex:0];
    [path setGravity:CGPointZero];
    
    if (type == eGT_WIN)
    {
        [[Utility getInstance] playEffect:SOUND_WIN];
//        [[[CCDirector sharedDirector] scheduler] setTimeScale:0.4];
        CCCallBlock *block = [CCCallBlock actionWithBlock:^{
            WinPopup *popup = [[WinPopup alloc] init];
            [[CCDirector sharedDirector].runningScene addChild:popup z:Z_RESULT_POPUP];
            [popup release];
//            [[[CCDirector sharedDirector] scheduler] setTimeScale:1.0];
        }];
        CCDelayTime *delay = [CCDelayTime actionWithDuration:0.4];
        CCSequence *seq = [CCSequence actions:delay, block, nil];
        [self runAction:seq];
        // self.runAction(seq);
        [self saveLevelDetail];
    }
    else
    {
//        [[[CCDirector sharedDirector] scheduler] setTimeScale:0.4];
        CCCallBlock *block = [CCCallBlock actionWithBlock:^{
//            LosePopup *popup = [[LosePopup alloc] initWithType:type];
//            [[CCDirector sharedDirector].runningScene addChild:popup z:Z_RESULT_POPUP];
//            [popup release];
//            [[[CCDirector sharedDirector] scheduler] setTimeScale:1.0];
            [self replay];
//            [self jailBreak]; // auto replay, remove via user's request
            
        }];
        CCDelayTime *delay = [CCDelayTime actionWithDuration:1];
        CCSequence *seq = [CCSequence actions:delay, block, nil];
        [self runAction:seq];
        
        // for effect
        if (type == eGT_BOMB)
        {
            CCSprite *spr = [CCSprite spriteWithSpriteFrameName:@"burn.png"];
            [spr setPosition:[[self getUserNode] getRealPosition]];
            [mGlobalBatch addChild:spr z:100];
        }
        else if (type == eGT_LAZER || type == eGT_BOUNC_BALL)
        {
            CCAction *action = [[Utility getInstance] getAnimWithKey:XML_ANIM_BOMB delay:0.02 loop:1];
            CCCallBlock *callBlock = [CCCallBlock actionWithBlock:^{
                [[self getUserNode] setVisible:NO];
                [[self getUserBlade] setVisible:NO];
                [[self getUserLine] setVisible:NO];
            }];
            CCSequence *sequence = [CCSequence actions:(CCFiniteTimeAction *)action, callBlock, nil];
            [[self getUserNode] runAction:sequence];
            [[self getUserNode] setScale:0.75];
            [self shakeScreen];
            [[Utility getInstance] playEffect:SOUND_BOMB_EXPLOSION];
        }
    }
}

-(void) saveLevelDetail
{
    LevelDetail *levelDetail = [[LevelManager getInstance] getCurrentLevelDetail];
    levelDetail._time = [LevelManager getInstance]._levelTime;
    levelDetail._energy = [LevelManager getInstance]._numEnergy;
    
    [[Utility getInstance] saveObject:levelDetail forKey:[[LevelManager getInstance] getCurrentLevelName]];
}

-(void) handleCollision:(b2Fixture *)fixtureA fixtureB:(b2Fixture *)fixtureB
{
    CCPhysicsSprite<PhysicInterface> *objectA = (CCPhysicsSprite<PhysicInterface> *)fixtureA->GetBody()->GetUserData();
    CCPhysicsSprite<PhysicInterface> *objectB = (CCPhysicsSprite<PhysicInterface> *)fixtureB->GetBody()->GetUserData();
    
    if (objectA == nil || objectB == nil)
        return;
    
    int typeA = [objectA getObjectType];
    int typeB = [objectB getObjectType];
    
    //--------------------------------------------------------------------
    if (typeA == eO_USER_NODE && typeB == eO_PATH_NODE)
    {
        [self handleNode:(PNode *)objectA pathNode:(PNode *)objectB];
    }
    else if (typeA == eO_PATH_NODE && typeB == eO_USER_NODE)
    {
        [self handleNode:(PNode *)objectB pathNode:(PNode *)objectA];
    }
    
    //--------------------------------------------------------------------
    else if (typeA == eO_BOMB && typeB == eO_USER_NODE)
    {
        [self handleBomb:(PNode *)objectB bomb:(Bomb *)objectA];
    }
    else if (typeA == eO_USER_NODE && typeB == eO_BOMB)
    {
        [self handleBomb:(PNode *)objectA bomb:(Bomb *)objectB];
    }
    
    //--------------------------------------------------------------------
    else if (typeA == eO_LAZER_LINE && typeB == eO_USER_NODE)
    {
        [self handleLazer:(PNode *)objectB lazer:(LLine *)objectA];
    }
    else if (typeA == eO_USER_NODE && typeB == eO_LAZER_LINE)
    {
        [self handleLazer:(PNode *)objectA lazer:(LLine *)objectB];
    }
    
    //--------------------------------------------------------------------
    else if (typeA == eO_ENERGY && typeB == eO_USER_NODE)
    {
        [self handleEnergy:(Energy *)objectA];
    }
    else if (typeA == eO_USER_NODE && typeB == eO_ENERGY)
    {
        [self handleEnergy:(Energy *)objectB];
    }
    
    //--------------------------------------------------------------------
    else if (typeA == eO_BOUNC_BALL && typeB == eO_USER_NODE)
    {
        [self handleBouncBall:(PNode *)objectB bouncBall:(BouncingBall *)objectA];
    }
    else if (typeA == eO_USER_NODE && typeB == eO_BOUNC_BALL)
    {
        [self handleBouncBall:(PNode *)objectA bouncBall:(BouncingBall *)objectB];
    }
    
    //--------------------------------------------------------------------
    else if (typeA == eO_ITEM && typeB == eO_USER_NODE)
    {
        [self handleItem:(PNode *)objectB item:(Item *)objectA];
    }
    else if (typeA == eO_USER_NODE && typeB == eO_ITEM)
    {
        [self handleItem:(PNode *)objectA item:(Item *)objectB];
    }
    
    //--------------------------------------------------------------------
    else if (typeA == eO_BOMB && typeB == eO_BOMB)
    {
        [self handleBombVsBomb:(Bomb *)objectA bomb2:(Bomb *)objectB];
    }
    
    //
    else if (typeA == eO_MAGNET && typeB == eO_ENERGY)
    {
        [self handleEnergy:(Energy *)objectB];
    }
    else if (typeA == eO_ENERGY && typeB == eO_MAGNET)
    {
        [self handleEnergy:(Energy *)objectA];
    }
    
    //
    else if (typeA == eO_BOMB_RANGE && typeB == eO_USER_NODE)
    {
        [self handleBombRange:(BombIndicator *)objectA];
    }
    else if (typeA == eO_USER_NODE && typeB == eO_BOMB_RANGE)
    {
        [self handleBombRange:(BombIndicator *)objectB];
    }
}

-(void) handleNode:(PNode *)userNode pathNode:(PNode *)pathNode
{
    if (pathNode._state != eNS_CONNECTING || mState == sMG_ENDING)
        return;
    
    Path *path = [mListPath objectAtIndex:0];
    [path connectWithNode:pathNode];
    [[Utility getInstance] playEffect:SOUND_NODE_CONNECT];
    if (pathNode.tag == 0)
    {
//        mState = sMG_STARTING;
//        [mMainGameUI showItem:NO];
        [path startSpread];
    }
    
    if (pathNode._nextNode == nil) // win here
    {
        [self endGame:eGT_WIN];
        CCLOG(@"win");
        return;
    }
}

-(void) handleBomb:(PNode *)userNode bomb:(Bomb *)bomb
{
    if (mState != sMG_STARTING)
        return;
    
    if (bomb._state == eBS_IDLE)
    {
        [bomb explode];
        ShieldZone *shield = (ShieldZone *)[self getChildByTag:TAG_SHIELD_ZONE];
        if (![shield destroyElement])
            [self endGame:eGT_BOMB];
    }
    else if (bomb._state == eBS_EPLOSION)
    {
        ShieldZone *shield = (ShieldZone *)[self getChildByTag:TAG_SHIELD_ZONE];
        if (![shield destroyElement])
            [self endGame:eGT_BOMB];
    }
}

-(void) handleLazer:(PNode *)userNode lazer:(LLine *)lazer
{
    
    if (mState != sMG_STARTING)
        return;
    
    if (lazer._state == eLLS_ON)
    {
        ShieldZone *shield = (ShieldZone *)[self getChildByTag:TAG_SHIELD_ZONE];
        if (![shield destroyElement])
            [self endGame:eGT_LAZER];
    }
    else
    {
        
    }
}

-(void) handleEnergy:(Energy *)energy
{
    if (mState != sMG_STARTING)
        return;
    
    if (!energy._isCollect)
    {
        [energy collect];
    }
}

-(void) handleBouncBall:(PNode *)userNode bouncBall:(BouncingBall *)bouncBall
{
    if (mState != sMG_STARTING)
        return;
    
    ShieldZone *shield = (ShieldZone *)[self getChildByTag:TAG_SHIELD_ZONE];
    if (![shield destroyElement])
    {
        [self endGame:eGT_BOUNC_BALL];
    }
    else
    {
        
    }
}

-(void) handleItem:(PNode *)userNode item:(Item *)item
{
    if (mState != sMG_STARTING)
        return;
    
    
}

-(void) handleBombVsBomb:(Bomb *)bomb1 bomb2:(Bomb *)bomb2
{
    if (bomb1._state == eBS_EPLOSION && bomb2._state == eBS_IDLE)
    {
        [bomb2 explode];
    }
    else if (bomb1._state == eBS_IDLE && bomb2._state == eBS_EPLOSION)
    {
        [bomb1 explode];
    }
}

-(void) handleBombRange:(BombIndicator *)bombI
{
    if (mState != sMG_STARTING)
        return;
    
    [bombI activeBomb];
}

-(PNode *) getUserNode
{
    Path *path = [mListPath objectAtIndex:0];
    return [path getUserNode];
}

-(CCBlade *) getUserBlade
{
    Path *path = [mListPath objectAtIndex:0];
    return [path getUserBlade];
}

-(PLine *) getUserLine
{
    Path *path = [mListPath objectAtIndex:0];
    return [path getUserLine];
}

-(void) dealloc
{
    m_Instance = nil;
    CCLOG(@"MainGameScene dealloc!");
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [self endGame];
    [super dealloc];
    
}

@end
